package cl.sujey.arrays;

import static org.junit.Assert.*;

import org.junit.Test;

public class MatrixTests {

	@Test
	public void testSetValue() throws Exception {

		double VALUE = 1;
		Position position = new Position(1, 1);

		/* Se setea el VALOR en la posicion 1, 1 */
		Matrix matrix = new Matrix(2, 2);
		matrix.setValue(position, VALUE);

		assertEquals(matrix.getValue(position), VALUE, 0);
	}

	@Test(expected = PositionOutOfBoundsException.class)
	public void testSetValueFail() throws Exception {

		double VALUE = 1;
		Position position = new Position(3, 3);

		/* Se setea el VALOR en la posicion 3, 3 */
		Matrix matrix = new Matrix(2, 2);
		matrix.setValue(position, VALUE);

	}

	@Test
	public void testIsOutOfBound() throws Exception {
		Matrix matrix = new Matrix(2, 2);
		Position position = new Position(3, 3);

		assertTrue(matrix.isOutOfBounds(position));
	}

	@Test
	public void testIsOutOfBound02() throws Exception {
		Matrix matrix = new Matrix(3, 3);
		Position position = new Position(2, 2);

		assertFalse(matrix.isOutOfBounds(position));
	}

	@Test
	public void testIsOutOfBound03() throws Exception {
		Matrix matrix = new Matrix(3, 3);
		Position position = new Position(1, 1);

		assertFalse(matrix.isOutOfBounds(position));
	}

	@Test
	public void testIsOutOfBound04() throws Exception {
		Matrix matrix = new Matrix(3, 3);
		Position position = new Position(3, 3);

		assertFalse(matrix.isOutOfBounds(position));
	}

	@Test
	public void testIsOutOfBoundFail01() throws Exception {
		Matrix matrix = new Matrix(2, 2);
		Position position = new Position(0, 0);

		assertTrue(matrix.isOutOfBounds(position));
	}

	@Test
	public void testIsOutOfBoundFail02() throws Exception {
		Matrix matrix = new Matrix(2, 2);
		Position position = new Position(-2, -2);

		assertTrue(matrix.isOutOfBounds(position));
	}

	@Test
	public void testIsOutOfBoundFail03() throws Exception {
		Matrix matrix = new Matrix(1, 3);
		Position position = new Position(3, 1);

		assertTrue(matrix.isOutOfBounds(position));
	}

	@Test
	public void testToString() throws Exception {
		Matrix matrix = new Matrix(2, 2);

		assertNotNull(matrix.toString());
	}

	@Test(expected = DifferentSizeException.class)
	public void testSumFail01() throws Exception {
		Matrix matrix = new Matrix(2, 2);
		Matrix matrix1 = new Matrix(3, 2);

		matrix.sum(matrix1);
	}

	/**
	 * TODO: Verificar que las sumas se hacen bien.
	 * 
	 * @throws Exception
	 */
	@Test()
	public void testSum01() throws Exception {

	}

	/**
	 * TODO: Hacer los casos de prueba.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testIsZero01() throws Exception {

		/* Se prepara la matriz */
		Matrix matrix = new Matrix(1, 1);
		Position position = new Position(1, 1);
		matrix.setValue(position, 0);

		assertTrue(matrix.isZero(position));
	}

	@Test
	public void testIsValid01() throws Exception {
		Matrix aMatrix = new Matrix(1, 1);

		assertTrue(aMatrix.isValid());
	}

	@Test
	public void testIsValid02() throws Exception {
		Matrix aMatrix = new Matrix(3, 8);

		assertTrue(aMatrix.isValid());
	}

	/**
	 * TODO: Hacer casos de prueba para la multiplicacion de matrices.
	 * 
	 * @throws Exception
	 */
	@Test
	public void testMultiply01() throws Exception {
		Matrix a = new Matrix(1, 1);
		a.setValue(new Position(1, 1), 3);

		Matrix b = new Matrix(1, 3);
		b.setValue(new Position(1, 1), 1);
		b.setValue(new Position(1, 2), 2);
		b.setValue(new Position(1, 3), 1);

		a.multiplication(b);
		assertEquals(1, a.getRows());
		assertEquals(3, b.getColumns());

		assertEquals(3, a.getValue(new Position(1, 1)), 0);
		assertEquals(6, a.getValue(new Position(1, 2)), 0);
		assertEquals(3, a.getValue(new Position(1, 3)), 0);
	}

	@Test
	public void testMultiply02() throws Exception {
		Matrix a = new Matrix(1, 1);
		a.setValue(new Position(1, 1), 0);

		Matrix b = new Matrix(1, 3);
		b.setValue(new Position(1, 1), 1);
		b.setValue(new Position(1, 2), 2);
		b.setValue(new Position(1, 3), 1);

		a.multiplication(b);
		assertEquals(1, a.getRows());
		assertEquals(3, b.getColumns());

		assertEquals(0, a.getValue(new Position(1, 1)), 0);
		assertEquals(0, a.getValue(new Position(1, 2)), 0);
		assertEquals(0, a.getValue(new Position(1, 3)), 0);
	}

	@Test
	public void testgetRow01() throws Exception {
		Matrix a = new Matrix(1, 1);
		a.setValue(new Position(1, 1), 3);

		double[] theRow = a.getRow(1);

		assertNotNull(theRow);
		assertEquals(1, theRow.length, 0);
		assertEquals(3, theRow[0], 0);
	}

    @Test
    public void testgetColumn01() throws Exception {
        Matrix a = new Matrix(1, 1);
        a.setValue(new Position(1, 1), 3);

        double[] theColumn = a.getColumn(1);

        assertNotNull(theColumn);
        assertEquals(1, theColumn.length, 0);
        assertEquals(3, theColumn[0], 0);
    }

    @Test
    public void testgetColumn02() throws Exception {
        Matrix a = new Matrix(2, 2);
        a.setValue(new Position(1,1), 3);
        a.setValue(new Position(1,2), 2);
        a.setValue(new Position(2,1), 4);
        a.setValue(new Position(2,2), 1);

        double[] theColumn = a.getColumn(1);

        assertNotNull(theColumn);
        assertEquals(2, theColumn.length, 0);
        assertEquals(3, theColumn[0], 0);
        assertEquals(4, theColumn[1], 0);
    }

    @Test(expected = ColumnOutOfRangeException.class)
    public void testgetColumnFail01() throws Exception {
        Matrix a = new Matrix(1, 1);
        a.setValue(new Position(1,1), 3);

        a.getColumn(2);
    }

    @Test(expected = ColumnOutOfRangeException.class)
    public void testgetColumnFail02() throws Exception {
        Matrix a = new Matrix(1, 1);
        a.setValue(new Position(1,1), -2);

        a.getColumn(0);
    }
}
